package com.ww.java.generic.wildcard;

public class CovariantArrays {

    public static void main(String[] args) {
        /**
         * 创建了一个Apple数组，并将其赋值给一个Fruit数组引用。这是有意义的，因为Apple也是一种Fruit，因此Apple数组也应该是一个Fruit数组
         */
        Fruit[] fruit = new Apple[10];
        fruit[0] = new Apple();
        fruit[1] = new Jonathan();

        /**
         * 如果实际的数组类型是Apple[]，你应该只能在其中放置Apple或Apple的子类型，这在编译期和运行时都可以工作。但是请注意，编译器允许你将
         * Fruit放置到这个数组中，这对于编译器来说是有意义的，因为它们有一个Fruit[]引用——它有什么理由不允许将Fruit对象或者任何从Fruit
         * 继承出来的对象，放置到这个数组中呢？
         * 因此，在编译期，这是允许的。但是在运行时数组机制知道它处理的是Apple[]，因此会在向数组中放置异构类型时抛出异常java.lang.ArrayStoreException
         *
         * 实际上，向上转型不合适用在这里。你真正做的是将一个数组赋值给另一个数组。数组的行为应该是它可以持有其他对象，这里只是因为我们能够
         * 向上转型而已，所以很明显，数组对象可以保留有关它们包含的对象类型的规则。
         */
        try {
            // 编译通过
            fruit[0] = new Fruit();
        } catch (Exception e) {
            // java.lang.ArrayStoreException: com.ww.java.generic.wildcard.Fruit
            System.out.println(e);
        }

        try {
            // 编译通过
            fruit[0] = new Orange();
        } catch (Exception e) {
            // java.lang.ArrayStoreException: com.ww.java.generic.wildcard.Orange
            System.out.println(e);
        }
    }
}

class Fruit {}

class Apple extends Fruit {}

class Jonathan extends Apple {}

class Orange extends Fruit {}